from django.db import models
from django.contrib.auth.models import AbstractUser
from utils.BaseModel import BaseModel

STATUS_CHOICES = (
    (0, "禁用"),
    (1, "启用"),
)


class UserProfile(AbstractUser, BaseModel):
    """
    模型：扩展用户信息
    添加了工号、部门等字段
    """
    name = models.CharField(max_length=40, verbose_name="姓名", help_text="姓名")
    GENDER_CHOICES = (
        (0, "女"),
        (1, "男"),
    )
    gender = models.IntegerField(choices=GENDER_CHOICES, default=1, null=True, blank=True, verbose_name="性别", help_text="性别")
    avatar = models.CharField(max_length=255, null=True, blank=True, verbose_name="头像", help_text="头像")
    mobile = models.CharField(max_length=12, blank=True, null=True, verbose_name='手机号码', help_text='手机号码')
    job_no = models.CharField(max_length=40, blank=True, null=True, verbose_name='工号')
    company = models.CharField(max_length=100, blank=True, null=True, verbose_name='所属公司')
    dept = models.ForeignKey(to='Dept', on_delete=models.PROTECT, db_constraint=False, blank=True, null=True, verbose_name='部门', help_text="部门")
    role = models.ManyToManyField(to='Role', db_constraint=False, verbose_name='角色', help_text="角色")

    class Meta:
        verbose_name = '用户信息表'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.username


class Dept(BaseModel):
    """
    模型：部门
    """
    name = models.CharField(max_length=64, verbose_name="部门名称", help_text="部门名称")
    sort = models.IntegerField(default=1, verbose_name="显示排序", null=True, blank=True, help_text="显示排序")
    owner = models.CharField(max_length=32, verbose_name="负责人", null=True, blank=True, help_text="负责人")
    phone = models.CharField(max_length=32, verbose_name="联系电话", null=True, blank=True, help_text="联系电话")
    email = models.EmailField(max_length=32, verbose_name="邮箱", null=True, blank=True, help_text="邮箱")
    status = models.IntegerField(choices=STATUS_CHOICES, default=1, null=True, blank=True, verbose_name="状态", help_text="状态")
    parent = models.ForeignKey(to='Dept', on_delete=models.CASCADE, default=None, db_constraint=False, null=True, blank=True, verbose_name="上级部门", help_text="上级部门")

    class Meta:
        verbose_name = '部门表'
        verbose_name_plural = verbose_name
        ordering = ('sort',)

    def __str__(self):
        return self.name


class Menu(BaseModel):
    """
    模型：菜单
    """
    name = models.CharField(max_length=64, verbose_name="菜单名称", help_text="菜单名称")
    sort = models.IntegerField(default=1, null=True, blank=True, verbose_name="显示排序", help_text="显示排序")
    icon = models.CharField(max_length=64, null=True, blank=True, verbose_name="菜单图标", help_text="菜单图标")
    web_path = models.CharField(max_length=128, null=True, blank=True, verbose_name="路由地址", help_text="路由地址")
    ISLINK_CHOICES = (
        (0, "否"),
        (1, "是"),
    )
    is_catalog = models.IntegerField(choices=ISLINK_CHOICES, default=0, verbose_name="是否目录", help_text="是否目录")
    is_link = models.IntegerField(choices=ISLINK_CHOICES, default=0, verbose_name="是否外链", help_text="是否外链")
    CACHE_CHOICES = (
        (0, '否'),
        (1, "是")
    )
    is_cache = models.IntegerField(choices=CACHE_CHOICES, default=0, verbose_name="是否页面缓存", help_text="是否页面缓存")
    VISIBLE_CHOICES = (
        (0, '不可见'),
        (1, "可见")
    )
    visible = models.IntegerField(choices=VISIBLE_CHOICES, default=1, verbose_name="侧边栏中是否显示", help_text="侧边栏中是否显示")
    status = models.IntegerField(choices=STATUS_CHOICES, default=1, verbose_name="状态", help_text="状态")
    parent = models.ForeignKey(to='Menu', on_delete=models.CASCADE, null=True, blank=True, db_constraint=False, verbose_name="上级菜单", help_text="上级菜单")

    class Meta:
        verbose_name = '菜单表'
        verbose_name_plural = verbose_name
        ordering = ('sort',)

    def __str__(self):
        return self.name


class MenuButton(BaseModel):
    """
    模型：菜单按钮权限
    """
    menu = models.ForeignKey(to="Menu", db_constraint=False, related_name="menuPermission", on_delete=models.CASCADE, verbose_name="关联菜单", help_text='关联菜单')
    name = models.CharField(max_length=64, verbose_name="按钮名称", help_text="按钮名称")
    key = models.CharField(max_length=64, verbose_name="按钮权限值", help_text="按钮权限值")

    class Meta:
        verbose_name = '菜单按钮权限表'
        verbose_name_plural = verbose_name
        ordering = ('-name',)

    def __str__(self):
        return self.name


class Role(BaseModel):
    """
    模型：角色
    """
    name = models.CharField(max_length=64, verbose_name="角色名称", help_text="角色名称")
    key = models.CharField(max_length=64, verbose_name="角色权限值", help_text="角色权限值")
    sort = models.IntegerField(default=1, null=True, blank=True, verbose_name="显示排序", help_text="显示排序")
    ADMIN_CHOICES = (
        (0, "否"),
        (1, "是"),
    )
    is_admin = models.IntegerField(choices=ADMIN_CHOICES, default=0, verbose_name="是否管理员", help_text="是否管理员")
    DATASCOPE_CHOICES = (
        (0, "仅本人数据权限"),
        (1, "本部门数据权限"),
        (2, "本部门及以下数据权限"),
        (3, "全部数据权限"),
        (4, "自定数据权限"),
    )
    data_range = models.IntegerField(default=0, choices=DATASCOPE_CHOICES, verbose_name="数据权限范围", help_text="数据权限范围")
    remark = models.CharField(max_length=500, null=True, blank=True, verbose_name="备注", help_text="备注")
    status = models.IntegerField(choices=STATUS_CHOICES, default=1, verbose_name="状态", help_text="状态")
    dept = models.ManyToManyField(to='Dept', db_constraint=False, verbose_name='数据权限-关联部门', help_text="数据权限-关联部门")
    menu = models.ManyToManyField(to='Menu', db_constraint=False, verbose_name='关联菜单', help_text="关联菜单")
    permission = models.ManyToManyField(to='MenuButton', db_constraint=False, verbose_name='关联菜单的接口按钮', help_text="关联菜单的接口按钮")

    class Meta:
        verbose_name = '角色表'
        verbose_name_plural = verbose_name
        ordering = ('sort',)

    def __str__(self):
        return self.name


class Dictionary(BaseModel):
    """
    模型：字典
    """
    code = models.CharField(max_length=100, blank=True, null=True, verbose_name="编码", help_text="编码")
    label = models.CharField(max_length=100, blank=True, null=True, verbose_name="显示名称", help_text="显示名称")
    value = models.CharField(max_length=100, blank=True, null=True, verbose_name="实际值", help_text="实际值")
    remark = models.CharField(max_length=2000, blank=True, null=True, verbose_name="备注", help_text="备注")
    sort = models.IntegerField(default=1, null=True, blank=True, verbose_name="显示排序", help_text="显示排序")
    STATUS_CHOICES = (
        (0, "禁用"),
        (1, "启用"),
    )
    status = models.IntegerField(choices=STATUS_CHOICES, default=1, verbose_name="状态", help_text="状态")
    parent = models.ForeignKey(to='self', related_name='sublist', db_constraint=False, on_delete=models.PROTECT, blank=True, null=True, verbose_name="父级", help_text="父级")

    class Meta:
        verbose_name = "字典表"
        verbose_name_plural = verbose_name
        ordering = ('sort',)

    def __str__(self):
        return self.label


class OperationLog(BaseModel):
    """
    模型：用户操作日志
    """
    request_modular = models.CharField(max_length=64, null=True, blank=True, verbose_name="请求模块", help_text="请求模块")
    request_method = models.CharField(max_length=8, null=True, blank=True, verbose_name="请求方式", help_text="请求方式")
    request_path = models.CharField(max_length=400, null=True, blank=True, verbose_name="请求地址", help_text="请求地址")
    request_body = models.TextField(null=True, blank=True, verbose_name="请求参数", help_text="请求参数")
    request_msg = models.TextField(null=True, blank=True, verbose_name="操作说明", help_text="操作说明")
    request_ip = models.CharField(max_length=32, null=True, blank=True, verbose_name="请求ip地址", help_text="请求ip地址")
    request_os = models.CharField(max_length=64, null=True, blank=True, verbose_name="操作系统", help_text="操作系统")
    request_browser = models.CharField(max_length=64, null=True, blank=True, verbose_name="请求浏览器", help_text="请求浏览器")
    response_code = models.CharField(max_length=32, null=True, blank=True, verbose_name="响应状态码", help_text="响应状态码")
    json_result = models.TextField(null=True, blank=True, verbose_name="返回信息", help_text="返回信息")
    status = models.BooleanField(default=False, verbose_name="响应状态", help_text="响应状态")

    class Meta:
        verbose_name = '用户操作日志表'
        verbose_name_plural = verbose_name
        ordering = ('-create_datetime',)

    def __str__(self):
        return self.request_modular + '.' + self.request_path


class WeChatUser(BaseModel):
    """
    模型：微信用户
    """
    server_user = models.OneToOneField('systems.UserProfile', on_delete=models.PROTECT, verbose_name='服务端用户', unique=True)
    nickname = models.CharField(max_length=255, null=True, blank=True, verbose_name="微信昵称")
    unionid = models.CharField(max_length=255, null=True, blank=True, verbose_name="微信用户唯一身份ID")
    openid = models.CharField(max_length=255, null=True, blank=True, verbose_name="微信用户对当前应用的唯一ID")
    session_key = models.CharField(max_length=255, null=True, blank=True, verbose_name="微信本地登录的会话密钥")
    access_token = models.CharField(max_length=255, null=True, blank=True, verbose_name="微信全局唯一后台接口调用凭据")
    expires_in = models.IntegerField(null=True, blank=True, verbose_name="token有效期")
    last_login_datetime = models.DateTimeField(null=True, blank=True, verbose_name='最后登陆时间')

    class Meta:
        verbose_name = '微信用户表'
        verbose_name_plural = verbose_name
        ordering = ['-create_datetime']

    def __str__(self):
        return self.unionid